package com.tvunetworks.center.user.service.impl;

import com.tvunetworks.center.common.constant.LocalConstant;
import com.tvunetworks.center.common.model.LoginUser;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.gs.model.Device;
import com.tvunetworks.center.user.mapper.BookingEventMapper;
import com.tvunetworks.center.user.mapper.UserDeviceMapper;
import com.tvunetworks.center.user.model.UserDevice;
import com.tvunetworks.center.user.model.vo.ExtBindReceiverVo;
import com.tvunetworks.center.user.service.BookmarkDeviceService;
import com.tvunetworks.center.user.service.ExtService;
import com.tvunetworks.center.user.service.UserDeviceService;
import com.tvunetworks.center.user.service.feign.DeviceFeignService;
import com.tvunetworks.center.user.util.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: tvucc-user
 * @description: ExtServiceImpl
 * @author lebronchen
 * @create: 2019-03-19 14:10
 **/
@Service
@Slf4j
public class ExtServiceImpl implements ExtService {

    @Autowired
    private UserDeviceMapper userDeviceMapper;
    @Autowired
    private DeviceFeignService deviceFeignService;
    @Autowired
    private BookingEventMapper bookingEventMapper;
    @Autowired
    private UserDeviceService userDeviceService;
    @Autowired
    private BookmarkDeviceService bookmarkDeviceService;

    @Value("${ext.type}")
    private String extType;

    @Override
    @Transactional
    public Result<String> addExtNoUser(String name, String url, String type, String rid,String remark) {
        // 调用Device服务创建Ext
        Device device = new Device();
        device.setName(name);
        device.setUrl(url);
        device.setType(type);
        device.setTimeStamp(System.currentTimeMillis()+"");
        if(remark !=null){
            device.setRemark(remark);
        }
        Result<String> addExtResult = deviceFeignService.addExt(device);
        if (!addExtResult.assertSuccess()) {
            return ResultUtil.error("81000102", "Add Ext failed from device server", addExtResult);
        }
        String extPeerId = addExtResult.getResult();
        if (StringUtils.isNotBlank(rid)) {
            deviceFeignService.addExtToReceiver(rid, extPeerId);
        }
        return ResultUtil.success(extPeerId);
    }

    @Override
    @Transactional
    public Result<String> addExtToUser(LoginUser loginUser, String name, String url, String type, String rid,String remark) {
        // 校验Ext的name，type是否存在一致的
        String types = UserUtil.packageExtTypesToString(extType);
        List<String> existExts = userDeviceMapper.listUserExistExt(loginUser.getId(), name, types);
        if (existExts != null && existExts.size() > 0) {
            return ResultUtil.error("81000101", "Name exist");
        }
        //校验webR中是否有相同名字Ext
        if (StringUtils.isNotEmpty(rid)) {
            try {
                List<Device> extFromWebR = deviceFeignService.getExtFromWebR(rid);
                if (!CollectionUtils.isEmpty(existExts)) {
                    List<Device> collect = extFromWebR.stream().filter(s -> StringUtils.equals(name, s.getName())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect)) {
                        return ResultUtil.error("81000101", "Name exist in WebR");
                    }
                }
            } catch (Exception e) {
                log.error("msg:{},e:{}",e.getMessage(),e);
            }
        }

        //添加ext到device中
        Result<String> result = this.addExtNoUser(name, url, type, rid, remark);
        if (!result.assertSuccess()) {
            return result;
        }
        String extPeerId = result.getResult();
        // 保存UserDevice
        UserDevice userDevice = new UserDevice();
        userDevice.setId(MyUtil.getUUID());
        userDevice.setUserId(loginUser.getId());
        userDevice.setPeerId(extPeerId);
        userDevice.setPostion(0);
        userDevice.setFlag(0);
        userDeviceMapper.insert(userDevice);
        if (LocalConstant.UserRole.ADMIN.equals(loginUser.getRole())) {
            userDevice.setFlag(1);
        } else {
            userDevice.setFlag(2);
        }
        userDevice.setId(MyUtil.getUUID());
        userDeviceMapper.insert(userDevice);
        return ResultUtil.success(extPeerId);
    }

    @Override
    @Transactional
    public Result updateExt(String peerId, String name, String url,String remark) {
        int existBooking = bookingEventMapper.countFutureEvent(peerId, System.currentTimeMillis());
        if (existBooking > 0) {
            return ResultUtil.error("81000801", "Event usering this source ,can not edit");
        }
        Device device = new Device()
                .setPeerId(peerId)
                .setUrl(url)
                .setName(name);
        if(remark != null){
            device.setRemark(remark);
        }
        Result<String> updateExtResult = deviceFeignService.updateExt(device);
        String errorCode = updateExtResult.getErrorCode();
        if (StringUtils.equals("101", errorCode)) {
            return ResultUtil.error("81000802", "Ext not exist");
        } else if (StringUtils.equals("102", errorCode)) {
            return ResultUtil.error("81000803", "Device not ext");
        }  else if (StringUtils.equals("103", errorCode)) {
            return ResultUtil.error("81000804", "Device is living");
        }
        return ResultUtil.success();
    }

    @Override
    @Transactional
    public Result<String> deleteExt(String peerId) {
        int existBooking = bookingEventMapper.countFutureEvent(peerId, System.currentTimeMillis());
        if (existBooking > 0) {
            return ResultUtil.error("81000801", "This source has already been scheduled by the Booking Service. Please remove the existing bookings to proceed.");
        }
        Result<String> deleteExtResult = deviceFeignService.deleteExt(peerId);
        String errorCode = deleteExtResult.getErrorCode();
        if (StringUtils.equals("101", errorCode)) {
            return ResultUtil.error("81000802", "Ext not exist");
        } else if (StringUtils.equals("102", errorCode)) {
            return ResultUtil.error("81000803", "Device not ext");
        }  else if (StringUtils.equals("103", errorCode)) {
            return ResultUtil.error("81000804", "Device is living");
        }
        userDeviceService.removeUserDevice(peerId);
        bookmarkDeviceService.removeBookmarkDeviceByPeerId(peerId);



        return ResultUtil.success();
    }

    @Override
    public List<ExtBindReceiverVo> listExtBindedRids(String userId, String peerId, String condition) {
        List<String> userRids = userDeviceService.listUserDevice(userId, condition, LocalConstant.DeviceType.R);
        if (CollectionUtils.isEmpty(userRids)) {
            return new ArrayList<>();
        }
        List<String> bindedRids = deviceFeignService.listExtBindedRids(peerId);
        if (CollectionUtils.isEmpty(bindedRids)) {
            return new ArrayList<>();
        }
        userRids.retainAll(bindedRids);
        if (CollectionUtils.isEmpty(userRids)) {
            return new ArrayList<>();
        }
        return userDeviceMapper.listExtBindReceiverVo(userRids);
    }

    @Override
    public List<ExtBindReceiverVo> listExtUnBindRids(String userId, String peerId, String condition) {
        List<String> userRids = userDeviceService.listUserDevice(userId, condition, LocalConstant.DeviceType.R);
        if (CollectionUtils.isEmpty(userRids)) {
            return new ArrayList<>();
        }
        List<String> bindedRids = deviceFeignService.listExtBindedRids(peerId);
        if (!CollectionUtils.isEmpty(bindedRids)) {
            userRids.removeAll(bindedRids);
        }
        if (CollectionUtils.isEmpty(userRids)) {
            return new ArrayList<>();
        }
        return userDeviceMapper.listExtBindReceiverVo(userRids);
    }

    @Override
    @Transactional
    public void correlateExtPairedR(String peerId, String addRids, String removeRids) {
        addRids = addRids.toLowerCase();
        removeRids = removeRids.toLowerCase();
        deviceFeignService.correlateExtPairedR(peerId, addRids, removeRids);
    }


    @Override
    @Transactional
    public Result<String> addExtToUserByCC(LoginUser loginUser, String name, String url, String type, String rid,String remark) {
        // 校验Ext的name，type是否存在一致的
        String types = UserUtil.packageExtTypesToString(extType);
        List<String> existExts = userDeviceMapper.listUserExistExt(loginUser.getId(), name, types);
        if (existExts != null && existExts.size() > 0) {
            return ResultUtil.error("81000101", "Name exist");
        }
        //校验webR中是否有相同名字Ext
        if (StringUtils.isNotEmpty(rid)) {
            try {
                List<Device> extFromWebR = deviceFeignService.getExtFromWebR(rid);
                if (!CollectionUtils.isEmpty(existExts)) {
                    List<Device> collect = extFromWebR.stream().filter(s -> StringUtils.equals(name, s.getName())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(collect)) {
                        return ResultUtil.error("81000101", "Name exist in WebR");
                    }
                }
            } catch (Exception e) {
                log.error("msg:{},e:{}",e.getMessage(),e);
            }
        }
        //校验该用户下是否有相同url的设备,如果有,则返回已有名字
        List<Device> device = userDeviceMapper.getExtByUrlAndUserId(url, loginUser.getId());
        if (!CollectionUtils.isEmpty(device)){
            return ResultUtil.success(device.get(1).getName());
        }

        //添加ext到device中
        Result<String> result = this.addExtNoUser(name, url, type, rid, remark);
        if (!result.assertSuccess()) {
            return result;
        }
        String extPeerId = result.getResult();
        // 保存UserDevice
        UserDevice userDevice = new UserDevice();
        userDevice.setId(MyUtil.getUUID());
        userDevice.setUserId(loginUser.getId());
        userDevice.setPeerId(extPeerId);
        userDevice.setPostion(0);
        userDevice.setFlag(0);
        userDeviceMapper.insert(userDevice);
        if (LocalConstant.UserRole.ADMIN.equals(loginUser.getRole())) {
            userDevice.setFlag(1);
        } else {
            userDevice.setFlag(2);
        }
        userDevice.setId(MyUtil.getUUID());
        userDeviceMapper.insert(userDevice);
        return ResultUtil.success();
    }
}
